package com.zyw.zhuangdian.aspect;

import com.zyw.zhuangdian.constant.ServiceConstant;
import com.zyw.zhuangdian.enums.MsgCode;
import com.zyw.zhuangdian.interceptor.JWTInterceptor;
import com.zyw.zhuangdian.pojo.Resp;
import com.zyw.zhuangdian.pojo.dto.HistoryDto;
import com.zyw.zhuangdian.property.MyProperties;
import com.zyw.zhuangdian.service.HistoryService;
import com.zyw.zhuangdian.util.Base64Util;
import com.zyw.zhuangdian.util.JWTUtil;
import com.zyw.zhuangdian.util.RespUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Order(-1)
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class LogAspect {

    private final HistoryService historyService;

    private final MyProperties properties;


    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void restController() {
    }

    @Pointcut("@annotation(com.zyw.zhuangdian.annotation.SysLog)")
    public void sysLog() {
    }

    @Around("restController()")
    public Object requestLog(ProceedingJoinPoint point) throws Throwable {
        HistoryDto history = new HistoryDto();
        ResponseEntity<Resp<?>> out = RespUtil.SYSTEM_ERROR(MsgCode.MSG_ERROR);
        // 取得请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        List<String> list = Arrays.stream(point.getArgs()).map(Object::toString).collect(Collectors.toList());

        log.info("==== 请求入参 ====:{}", String.join("|", list));
        // 此处如果catch了异常，会影响全局 异常捕捉器 无效
//        try {
            history.setRequestContent(String.join("|", list));
            history.setApi(request.getRequestURI());
            history.setIp(JWTInterceptor.getIpAddress(request));
            // 获取uid
            String uid = "未知uid";
            if (StringUtils.isNotBlank(request.getHeader(JWTUtil.AUTH_HEADER_KEY))) {
                String token = request.getHeader(JWTUtil.AUTH_HEADER_KEY).replace(properties.getTokenPrefix(), "");
                uid = JWTUtil.getUserId(token);
            }
            history.setUid(uid);
            // 获取用户昵称
            String nickname = "未知用户";
            if (StringUtils.isNotBlank(request.getHeader(ServiceConstant.NICKNAME))) {
                String str = request.getHeader(ServiceConstant.NICKNAME);
                nickname = Base64Util.decode(str);
            }
            history.setNickname(nickname);
            out = (ResponseEntity<Resp<?>>) point.proceed();
            log.info("==== 请求出参 ====:{}", out);
            history.setResponseHttpCode(out.getStatusCode().toString());
            history.setResponseContent(String.valueOf(out.getBody()));
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
            log.info(history.toString());
//            historyService.addHistory(history);
//        }

        return out;
    }
}
